package org.iteam.bank.signed.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.iteam.bank.mina.client.ResultMessage;
import org.iteam.bank.signed.model.AccountBalance;
import org.iteam.bank.signed.model.P2POrder;
import org.iteam.bank.signed.model.P2PPayAccount;
import org.iteam.bank.signed.model.P2PProject;
import org.iteam.commons.codec.MD5Coder;
import org.iteam.db.SimpleDbRunner;
import org.iteam.db.exception.DbException;
import org.iteam.mina.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class SubscribeService {
	private static final Logger logger = LoggerFactory.getLogger(SubscribeService.class);

	private SubscribeService() {
		super();
	}

	public static SubscribeService getInstance() {
		return Subclass.service;
	}

	private static final class Subclass {
		public static final SubscribeService service = new SubscribeService();
	}

	// 支付密码 MD5(MD5(明文)+"YTHFX")
	private static final String PAY_SOLT = "YTHFX";// 支付密码固定加密戳//支付密码

	// MD5(MD5(明文)+"YTHFX")

	/**
	 * 加密支付密码
	 *
	 * @param password
	 * @return
	 */
	public static String encryptionPayPassword(String password) {
		return MD5Coder.md5Hex(password.concat(PAY_SOLT));
	}

	/**
	 * 产品认购
	 *
	 * @param p2p_user_id
	 * @param p2p_project_id
	 * @param dealno
	 * @param ip
	 * @param p2pPayAccount
	 * @param accountBalance
	 * @param errorMsg
	 * @return
	 * @throws SQLException
	 */
	public synchronized boolean orderPay(String p2p_user_id, String p2p_project_id, String dealno, String ip, P2PPayAccount p2pPayAccount,
			AccountBalance accountBalance, StringBuffer errorMsg) throws DbException {
		// 修改订单状态
		// 修改项目信息
		// 添加交易流水
		// 添加用户投资记录
		// 添加用户日志

		SimpleDbRunner dbHandle = null;
		SimpleDbRunner dbPayHandle = null;
		String createBy = "PC";
		String thirdDealNo = null;// 第三方交易流水号
		String contractNo = null;// 合同编号
		long currentTimeMillis = System.currentTimeMillis();
		// 产品认购状态 true：成功，false：失败（包含处理中，以后人工处理）
		boolean subscribeResult = false;
		// 是否写入数据库
		boolean isWritingDB = false;
		boolean result = false;
		try {

			dbHandle = new SimpleDbRunner(true);
			dbPayHandle = new SimpleDbRunner(org.iteam.bank.core.Constant.MYSQL_PAY, true);
			P2POrder p2pOrder = P2POrderService.getInstance().show(dbHandle, dealno);
			P2PProject p2pProject = P2PProjectService.getInstance().show(dbHandle, p2p_project_id);
			long shortCurrentTime = currentTimeMillis / 1000;
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String currentTime = format.format(currentTimeMillis);
			String p2p_transaction_flow_id = p2pOrder.getId();
			// 系统交易流水号
			String localDealNo = dealno;
			// 添加交易流水
			StringBuffer columnNames_p2p_transaction_flow = new StringBuffer(
					"accountBalance,amountVerify,bp,callbackParams,callbackTime,callbackUrl,dealAmount,dealFee,");
			columnNames_p2p_transaction_flow.append("dealStatus,dealType,ip,localDealNo,remark,requestParams,requestTime,requestUrl,");
			columnNames_p2p_transaction_flow.append("sortId,thirdDealNo,collect_user,p2pOrder_id,pay_user");
			String insert_p2p_transaction_flow = ZDSQL.sql("p2p_transaction_flow", columnNames_p2p_transaction_flow.toString());
			List<Object> params_p2p_transaction_flow = ZDSQL.initParams(p2p_transaction_flow_id, createBy, currentTime);
			params_p2p_transaction_flow.add(accountBalance.getAccountBalance());
			params_p2p_transaction_flow.add(accountBalance.getAvailableBalance().subtract(p2pOrder.getAmount()));
			params_p2p_transaction_flow.add(0);// 0 支出 1 收入 2冻结 3 解冻
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(shortCurrentTime);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(p2pOrder.getAmount());
			params_p2p_transaction_flow.add(0);
			// * 10 申请* 20 成功 21 资金退回 22 第三方处理失败* 30 失败
			params_p2p_transaction_flow.add(20);
			// 10 充值 * 20 提现* 30 投标 * 40 收款* 50 还款* 61 提现手续费 62 交易手续费63 担保费 64
			// 佣金 60 利息管理费* 70 80 90 100（备用）
			params_p2p_transaction_flow.add(30);
			params_p2p_transaction_flow.add(ip);
			params_p2p_transaction_flow.add(localDealNo);
			params_p2p_transaction_flow.add("投标成功！");
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(shortCurrentTime);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(p2pProject.getP2pUser_id());
			params_p2p_transaction_flow.add(p2pOrder.getId());
			params_p2p_transaction_flow.add(p2p_user_id);

			// 添加用户投资记录
			StringBuffer columnNames_p2p_user_invest = new StringBuffer("award,collectedCaptical,collectedInterest,collectedPeriod,collectedTotal");
			columnNames_p2p_user_invest.append(",collectedoverdueInterest,dueInCapital,dueInInterest,dueInTotal,expectIncome,interestFee,investAmout,");
			columnNames_p2p_user_invest.append("investDate,investPeriod,investType,investVerifyAmount,investWay,isTransfer,isaward,");
			columnNames_p2p_user_invest.append("nextCollectAmount,nextCollectDate,overdueDay,overdueInterest,shouldCollectCapital,shouldCollectInterest,");
			columnNames_p2p_user_invest.append("shouldCollectOverdueAmt,shouldCollectTotal,status,transferPeriod,orderId,p2pProject_id,p2pUser_id");
			String insert_p2p_user_invest = ZDSQL.sql("p2p_user_invest", columnNames_p2p_user_invest.toString());
			List<Object> params_user_invest = ZDSQL.initParams(p2p_transaction_flow_id, createBy, currentTime);

			params_user_invest.add(null); // award decimal(19,2) YES
			params_user_invest.add(0); // collectedCaptical decimal(19,2) YES
			params_user_invest.add(0); // collectedInterest decimal(19,2) YES
			params_user_invest.add(null); // collectedPeriod int(11) YES
			params_user_invest.add(0); // collectedTotal decimal(19,2) YES
			params_user_invest.add(0); // collectedoverdueInterest decimal(19,2)
			// YES
			params_user_invest.add(0); // dueInCapital decimal(19,2) YES
			params_user_invest.add(0);// dueInInterest decimal(19,2) YES
			params_user_invest.add(0);// dueInTotal decimal(19,2) YES
			// 预期收益
			BigDecimal expectIncome = null;
			switch (p2pProject.getPeriodType()) {
			case P2PProject.SCALE_TYPE_DAY:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(360), 2, BigDecimal.ROUND_HALF_UP);
				break;
			case P2PProject.SCALE_TYPE_MONTH:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(12), 2, BigDecimal.ROUND_HALF_UP);
				break;
			case P2PProject.SCALE_TYPE_YEAR:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP);
				break;
			default:
				expectIncome = new BigDecimal(0);
				break;
			}

			params_user_invest.add(expectIncome);// expectIncome decimal(19,2)
			// YES
			params_user_invest.add(0);// interestFee decimal(19,2) YES
			params_user_invest.add(p2pOrder.getAmount());// investAmout
			// decimal(19,2) YES
			params_user_invest.add(shortCurrentTime);// investDate bigint(20)
			// YES
			params_user_invest.add(null);// investPeriod int(11) YES
			params_user_invest.add(null);// investType varchar(255) YES
			params_user_invest.add(p2pOrder.getAmount());// investVerifyAmount
			// decimal(19,2)
			// YES
			params_user_invest.add(1);// investWay int(11) YES 0 自动投标 1 网站手动 2
			// // 手机手动
			params_user_invest.add(null);// isTransfer int(11) YES
			params_user_invest.add(null);// isaward int(11) YES
			params_user_invest.add(0);// nextCollectAmount decimal(19,2) YES
			params_user_invest.add(null);// nextCollectDate bigint(20) YES
			params_user_invest.add(0);// overdueDay int(11) YES
			params_user_invest.add(0);// overdueInterest decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectCapital decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectInterest decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectOverdueAmt decimal(19,2)
			// YES
			params_user_invest.add(0);// shouldCollectTotal decimal(19,2) YES
			params_user_invest.add(2);// status int(11) YES 0 全部未通过 1 部分通过 2
			// 全部通过
			params_user_invest.add(null);// transferPeriod int(11) YES
			params_user_invest.add(p2pOrder.getId());// orderId varchar(32) YES
			// MUL
			params_user_invest.add(p2p_project_id);// p2pProject_id varchar(32)
			// YES MUL
			params_user_invest.add(p2p_user_id);// p2pUser_id varchar(32) YES
			// MUL

			// 01：交易流水
			result = dbHandle.update(insert_p2p_transaction_flow, params_p2p_transaction_flow.toArray()) == 1;
			if (result) {
				// 02:用户投资记录
				result = result && dbHandle.update(insert_p2p_user_invest, params_user_invest.toArray()) == 1;
			}
			if (result) {
				// 03:添加用户日志（没有？？）
				// result = result &&
				// P2PUserLogService.getInstance().insert(currentTime,
				// P2PUserLogType.INVESTMEN_APPLY_MSG,
				// P2PUserLogType.INVESTMEN_APPLY, p2p_user_id);
			}

			// 04 : 调用银行
			if (result) {
				try {
					ResultMessage res = GSPService.getInstance().subscribe(dealno, p2pProject.getProjectCode(), p2p_user_id, p2pPayAccount.getEcard_no(),
							p2pPayAccount.getProtocol_no(), p2pPayAccount.getName(), p2pPayAccount.getCertificate_no(), p2pProject.getProductNo(),
							p2pProject.getProjectName(), p2pOrder.getAmount());

					if (res.isSuccess() && res.verify()) {
						res.decrypt();
						JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
						logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());
						subscribeResult = true;
						thirdDealNo = jsonObject.getString("channelSerialNo");
						contractNo = jsonObject.getString("contractNo");
						errorMsg.append("产品投资成功");
						isWritingDB = true;
					} else {
						// 农商行子网关处理中【网络原因和银行中断】
						if (res.isProcessing()) {
							logger.debug("{},农商行认购处理中，开始查询处理结果 ", dealno);
							// 04-02 进入产品状态查询
							subscribeResult = false;
							isWritingDB = true;
							res = GSPService.getInstance().subscribeStatusQuery(dealno);
							if (res.isSuccess() && res.verify()) {
								res.decrypt();
								JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
								logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());
								subscribeResult = true;
								thirdDealNo = jsonObject.getString("channelSerialNo");
								contractNo = jsonObject.getString("contractNo");
								errorMsg.append("产品投资成功");
								isWritingDB = true;
							} else {
								// 农商行子网关处理中【网络原因和银行中断】
								if (res.isProcessing()) {
									subscribeResult = false;
									isWritingDB = true;
									errorMsg.append("本次交易处理中,请联系客服处理");
								} else {
									subscribeResult = false;
									isWritingDB = false;
									if (res.verify()) {
										res.decrypt();
										// 银行返回错误提示
										if (res.isBankResult()) {
											JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
											errorMsg.append(jsonObject.getString("returnStatusMsg"));
											logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());
										}
										if (res.isRCBBankResult()) {
											JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
											errorMsg.append(jsonObject.getString("returnCodeMsg"));
											logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());

										}
									}
								}
							}
						} else {
							subscribeResult = false;
							isWritingDB = false;
							if (res.verify()) {
								res.decrypt();
								// 银行返回错误提示
								if (res.isBankResult()) {
									JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
									errorMsg.append(jsonObject.getString("returnStatusMsg"));
									logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());

								}
								if (res.isRCBBankResult()) {
									JSONObject jsonObject = JSON.parseObject(new String(res.getContent(), Constant.UTF_8));
									errorMsg.append(jsonObject.getString("returnCodeMsg"));
									logger.debug("{},产品认购结果:{}", dealno, jsonObject.toJSONString());

								}
							}
						}
						logger.debug("{},产品认购失败:{}", dealno, res.toString());
					}
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					subscribeResult = false;
					isWritingDB = false;
					errorMsg.append("产品认购失败,请稍候重试");
				}
			}
			if (result) {
				// 05:修改订单状态
				String updateOrderState = "update p2p_order set status = ?,relationId=?  where dealno = ? ";
				// 产品认购状态 判断？ 1成功，0失败，-1 申请
				if (subscribeResult) {
					result = dbHandle.update(updateOrderState, 1, p2p_transaction_flow_id, dealno) == 1;
				} else {
					result = dbHandle.update(updateOrderState, 0, p2p_transaction_flow_id, dealno) == 1;
				}
			}
			if (result && subscribeResult) {
				// 修改项目已投金额
				StringBuffer update_project_state = new StringBuffer("update p2p_project set updateBy=?,updateTime=?,");
				update_project_state.append(" version=version+1, castAmount=castAmount+? ");
				update_project_state.append(" where id  = ? and (projectAmount-castAmount)>=?  and status = 30 ");
				// 06:修改项目已投金额
				result = result
						&& dbHandle.update(update_project_state.toString(), createBy, currentTime, p2pOrder.getAmount(), p2p_project_id, p2pOrder.getAmount()) == 1;
			}
			// 07: 判断项目已投金额已满（修改项目状态为已满标）
			if (result && subscribeResult) {
				if (p2pProject.getCastAmount().add(p2pOrder.getAmount()).compareTo(p2pProject.getProjectAmount()) == 0) {
					StringBuffer update_project_fullScale = new StringBuffer("update p2p_project set updateBy=?,updateTime=?, ");
					update_project_fullScale.append(" version=version+1, fullScaleTime=? ,status = 60 ");
					update_project_fullScale.append(" where id  = ? and projectAmount=castAmount and status = 30 ");
					result = result && dbHandle.update(update_project_fullScale.toString(), createBy, currentTime, shortCurrentTime, p2p_project_id) == 1;
				}
			}
			// 08： 调用银行成功后修改系统交易流水中的三方交易流水号
			if (result) {
				String updateSQl = "update  p2p_transaction_flow set  thirdDealNo = ?,dealStatus = ?  where id = ? ";
				// 产品认购状态 判断？ * 10 申请* 20 成功 21 资金退回 22 第三方处理失败* 30 失败
				if (subscribeResult) {
					result = dbHandle.update(updateSQl, thirdDealNo, 20, p2p_transaction_flow_id) == 1;
				} else {
					result = dbHandle.update(updateSQl, null, 30, p2p_transaction_flow_id) == 1;
				}
			}
			// 09:修改用户投资记录状态
			if (result && !subscribeResult) {
				// 0 全部未通过 1 部分通过 2 全部通过
				String sql = "update p2p_user_invest set status = ?,investVerifyAmount=0  where id = ? ";
				result = dbHandle.update(sql, 0, p2p_transaction_flow_id) == 1;
			}
			// 10:添加支付库 投资合同表
			if (result && subscribeResult) {
				StringBuffer sql = new StringBuffer();
				sql.append("insert into pay_p2p_relate(p2p_id,request_id,pay_id,product_id,extra) values(?,?,?,?,?)");
				List<Object> params = new ArrayList<Object>();
				params.add(p2p_transaction_flow_id);
				params.add(dealno);
				params.add(contractNo);
				params.add(p2p_project_id);
				params.add(null);
				result = dbPayHandle.update(sql.toString(), params.toArray()) == 1;
			}

			if (result && isWritingDB) {
				dbHandle.commit();
				dbPayHandle.commit();
				if (subscribeResult) {
					errorMsg.setLength(0);
					errorMsg.append("产品认购成功");
				}
				return subscribeResult;
			} else {
				if (errorMsg.length() == 0) {
					errorMsg.append("产品认购失败,请稍候重试");
				}
				dbHandle.rollback();
				dbPayHandle.rollback();
			}
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			if (dbHandle != null)
				dbHandle.rollback();
			if (dbPayHandle != null)
				dbPayHandle.rollback();
			errorMsg.setLength(0);
			errorMsg.append("产品认购失败,请稍候重试");
			// TODO 如果系统数据库异常　重新执行一次
			if (isWritingDB) {
				errorMsg.setLength(0);
				return orderAddDataPay(p2p_user_id, p2p_project_id, dealno, ip, p2pPayAccount, accountBalance, errorMsg, thirdDealNo, contractNo,
						currentTimeMillis);
			}
		} finally {
			if (dbHandle != null)
				dbHandle = null;
			if (dbPayHandle != null)
				dbPayHandle = null;
		}

		return false;
	}

	private class OrderPayAddRunnable implements Runnable {
		String p2p_user_id;
		String p2p_project_id;
		String dealno;
		String ip;
		P2PPayAccount p2pPayAccount;
		AccountBalance accountBalance;
		StringBuffer errorMsg;
		String thirdDealNo;
		String contractNo;
		long currentTimeMillis;

		public OrderPayAddRunnable(String p2p_user_id, String p2p_project_id, String dealno, String ip, P2PPayAccount p2pPayAccount,
				AccountBalance accountBalance, StringBuffer errorMsg, String thirdDealNo, String contractNo, long currentTimeMillis) {
			this.p2p_user_id = p2p_user_id;
			this.p2p_project_id = p2p_project_id;
			this.dealno = dealno;
			this.ip = ip;
			this.p2pPayAccount = p2pPayAccount;
			this.accountBalance = accountBalance;
			this.errorMsg = errorMsg;
			this.thirdDealNo = thirdDealNo;
			this.contractNo = contractNo;
			this.currentTimeMillis = currentTimeMillis;
		}

		@Override
		public void run() {
			try {
				orderAddDataPay(p2p_user_id, p2p_project_id, dealno, ip, p2pPayAccount, accountBalance, errorMsg, thirdDealNo, contractNo, currentTimeMillis);
			} catch (DbException e) {
				logger.error(e.getMessage());
			}
		}
	}

	/**
	 * 产品认购
	 *
	 * @param p2p_user_id
	 *            用户ID
	 * @param p2p_project_id
	 *            p2p项目
	 * @param dealno
	 *            订单号
	 * @param ip
	 *            ip
	 * @param p2pPayAccount
	 *            支付信息
	 * @param accountBalance
	 *            账号信息
	 * @param errorMsg
	 * @param thirdDealNo
	 *            第三方交易流水号
	 * @param contractNo
	 *            合同号
	 * @param currentTimeMillis
	 *            认购时间
	 * @return
	 * @throws SQLException
	 */
	public synchronized boolean orderAddDataPay(String p2p_user_id, String p2p_project_id, String dealno, String ip, P2PPayAccount p2pPayAccount,
			AccountBalance accountBalance, StringBuffer errorMsg, String thirdDealNo, String contractNo, long currentTimeMillis) throws DbException {
		// 修改订单状态
		// 修改项目信息
		// 添加交易流水
		// 添加用户投资记录
		// 添加用户日志

		SimpleDbRunner dbHandle = null;
		SimpleDbRunner dbPayHandle = null;
		String createBy = "PC";
		try {

			dbHandle = new SimpleDbRunner(true);
			dbPayHandle = new SimpleDbRunner(org.iteam.bank.core.Constant.MYSQL_PAY, true);
			P2POrder p2pOrder = P2POrderService.getInstance().show(dbHandle, dealno);
			P2PProject p2pProject = P2PProjectService.getInstance().show(dbHandle, p2p_project_id);
			long shortCurrentTime = currentTimeMillis / 1000;
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String currentTime = format.format(currentTimeMillis);
			String p2p_transaction_flow_id = p2pOrder.getId();
			// 系统交易流水号
			String localDealNo = dealno;
			// 添加交易流水
			StringBuffer columnNames_p2p_transaction_flow = new StringBuffer(
					"accountBalance,amountVerify,bp,callbackParams,callbackTime,callbackUrl,dealAmount,dealFee,");
			columnNames_p2p_transaction_flow.append("dealStatus,dealType,ip,localDealNo,remark,requestParams,requestTime,requestUrl,");
			columnNames_p2p_transaction_flow.append("sortId,thirdDealNo,collect_user,p2pOrder_id,pay_user");
			String insert_p2p_transaction_flow = ZDSQL.sql("p2p_transaction_flow", columnNames_p2p_transaction_flow.toString());
			List<Object> params_p2p_transaction_flow = ZDSQL.initParams(p2p_transaction_flow_id, createBy, currentTime);
			params_p2p_transaction_flow.add(accountBalance.getAccountBalance());
			params_p2p_transaction_flow.add(accountBalance.getAvailableBalance().subtract(p2pOrder.getAmount()));
			params_p2p_transaction_flow.add(0);// 0 支出 1 收入 2冻结 3 解冻
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(shortCurrentTime);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(p2pOrder.getAmount());
			params_p2p_transaction_flow.add(0);
			// * 10 申请* 20 成功 21 资金退回 22 第三方处理失败* 30 失败
			params_p2p_transaction_flow.add(20);
			// 10 充值 * 20 提现* 30 投标 * 40 收款* 50 还款* 61 提现手续费 62 交易手续费63 担保费 64
			// 佣金 60 利息管理费* 70 80 90 100（备用）
			params_p2p_transaction_flow.add(30);
			params_p2p_transaction_flow.add(ip);
			params_p2p_transaction_flow.add(localDealNo);
			params_p2p_transaction_flow.add("投标成功！");
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(shortCurrentTime);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(null);
			params_p2p_transaction_flow.add(p2pProject.getP2pUser_id());
			params_p2p_transaction_flow.add(p2pOrder.getId());
			params_p2p_transaction_flow.add(p2p_user_id);

			// 添加用户投资记录
			StringBuffer columnNames_p2p_user_invest = new StringBuffer("award,collectedCaptical,collectedInterest,collectedPeriod,collectedTotal");
			columnNames_p2p_user_invest.append(",collectedoverdueInterest,dueInCapital,dueInInterest,dueInTotal,expectIncome,interestFee,investAmout,");
			columnNames_p2p_user_invest.append("investDate,investPeriod,investType,investVerifyAmount,investWay,isTransfer,isaward,");
			columnNames_p2p_user_invest.append("nextCollectAmount,nextCollectDate,overdueDay,overdueInterest,shouldCollectCapital,shouldCollectInterest,");
			columnNames_p2p_user_invest.append("shouldCollectOverdueAmt,shouldCollectTotal,status,transferPeriod,orderId,p2pProject_id,p2pUser_id");
			String insert_p2p_user_invest = ZDSQL.sql("p2p_user_invest", columnNames_p2p_user_invest.toString());
			List<Object> params_user_invest = ZDSQL.initParams(p2p_transaction_flow_id, createBy, currentTime);

			params_user_invest.add(null); // award decimal(19,2) YES
			params_user_invest.add(0); // collectedCaptical decimal(19,2) YES
			params_user_invest.add(0); // collectedInterest decimal(19,2) YES
			params_user_invest.add(null); // collectedPeriod int(11) YES
			params_user_invest.add(0); // collectedTotal decimal(19,2) YES
			params_user_invest.add(0); // collectedoverdueInterest decimal(19,2)
			// YES
			params_user_invest.add(0); // dueInCapital decimal(19,2) YES
			params_user_invest.add(0);// dueInInterest decimal(19,2) YES
			params_user_invest.add(0);// dueInTotal decimal(19,2) YES
			// 预期收益
			BigDecimal expectIncome = null;
			switch (p2pProject.getPeriodType()) {
			case P2PProject.SCALE_TYPE_DAY:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(360), 2, BigDecimal.ROUND_HALF_UP);
				break;
			case P2PProject.SCALE_TYPE_MONTH:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(12), 2, BigDecimal.ROUND_HALF_UP);
				break;
			case P2PProject.SCALE_TYPE_YEAR:
				expectIncome = p2pOrder.getAmount().multiply(p2pProject.getRate()).multiply(new BigDecimal(p2pProject.getPeriod()))
						.divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP);
				break;
			default:
				expectIncome = new BigDecimal(0);
				break;
			}

			params_user_invest.add(expectIncome);// expectIncome decimal(19,2)
			// YES
			params_user_invest.add(0);// interestFee decimal(19,2) YES
			params_user_invest.add(p2pOrder.getAmount());// investAmout
			// decimal(19,2) YES
			params_user_invest.add(shortCurrentTime);// investDate bigint(20)
			// YES
			params_user_invest.add(null);// investPeriod int(11) YES
			params_user_invest.add(null);// investType varchar(255) YES
			params_user_invest.add(p2pOrder.getAmount());// investVerifyAmount
			// decimal(19,2)
			// YES
			params_user_invest.add(1);// investWay int(11) YES 0 自动投标 1 网站手动 2
			// // 手机手动
			params_user_invest.add(null);// isTransfer int(11) YES
			params_user_invest.add(null);// isaward int(11) YES
			params_user_invest.add(0);// nextCollectAmount decimal(19,2) YES
			params_user_invest.add(null);// nextCollectDate bigint(20) YES
			params_user_invest.add(0);// overdueDay int(11) YES
			params_user_invest.add(0);// overdueInterest decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectCapital decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectInterest decimal(19,2) YES
			params_user_invest.add(0);// shouldCollectOverdueAmt decimal(19,2)
			// YES
			params_user_invest.add(0);// shouldCollectTotal decimal(19,2) YES
			params_user_invest.add(2);// status int(11) YES 0 全部未通过 1 部分通过 2
			// 全部通过
			params_user_invest.add(null);// transferPeriod int(11) YES
			params_user_invest.add(p2pOrder.getId());// orderId varchar(32) YES
			// MUL
			params_user_invest.add(p2p_project_id);// p2pProject_id varchar(32)
			// YES MUL
			params_user_invest.add(p2p_user_id);// p2pUser_id varchar(32) YES
			// MUL

			boolean result = false;
			// 01：交易流水
			result = dbHandle.update(insert_p2p_transaction_flow, params_p2p_transaction_flow.toArray()) == 1;
			if (result) {
				// 02:用户投资记录
				result = result && dbHandle.update(insert_p2p_user_invest, params_user_invest.toArray()) == 1;
			}
			if (result) {
				// 03:添加用户日志（没有？？）
				// result = result &&
				// P2PUserLogService.getInstance().insert(currentTime,
				// P2PUserLogType.INVESTMEN_APPLY_MSG,
				// P2PUserLogType.INVESTMEN_APPLY, p2p_user_id);
			}
			// 产品认购状态 true：成功，false：失败（包含处理中，以后人工处理）
			boolean subscribeResult = false;

			// 是否写入数据库
			boolean isWritingDB = false;

			// 04 : 调用银行
			if (result) {
				isWritingDB = true;
				subscribeResult = true;
			}
			if (result) {
				// 05:修改订单状态
				String updateOrderState = "update p2p_order set status = ?,relationId=?  where dealno = ? ";
				// 产品认购状态 判断？ 1成功，0失败，-1 申请
				if (subscribeResult) {
					result = dbHandle.update(updateOrderState, 1, p2p_transaction_flow_id, dealno) == 1;
				} else {
					result = dbHandle.update(updateOrderState, 0, p2p_transaction_flow_id, dealno) == 1;
				}
			}
			if (result && subscribeResult) {
				// 修改项目已投金额
				StringBuffer update_project_state = new StringBuffer("update p2p_project set updateBy=?,updateTime=?,");
				update_project_state.append(" version=version+1, castAmount=castAmount+? ");
				update_project_state.append(" where id  = ? and (projectAmount-castAmount)>=?  and status = 30 ");
				// 06:修改项目已投金额
				result = result
						&& dbHandle.update(update_project_state.toString(), createBy, currentTime, p2pOrder.getAmount(), p2p_project_id, p2pOrder.getAmount()) == 1;
			}
			// 07: 判断项目已投金额已满（修改项目状态为已满标）
			if (result && subscribeResult) {
				if (p2pProject.getCastAmount().add(p2pOrder.getAmount()).compareTo(p2pProject.getProjectAmount()) == 0) {
					StringBuffer update_project_fullScale = new StringBuffer("update p2p_project set updateBy=?,updateTime=?, ");
					update_project_fullScale.append(" version=version+1, fullScaleTime=? ,status = 60 ");
					update_project_fullScale.append(" where id  = ? and projectAmount=castAmount and status = 30 ");
					result = result && dbHandle.update(update_project_fullScale.toString(), createBy, currentTime, shortCurrentTime, p2p_project_id) == 1;
				}
			}
			// 08： 调用银行成功后修改系统交易流水中的三方交易流水号
			if (result) {
				String updateSQl = "update  p2p_transaction_flow set  thirdDealNo = ?,dealStatus = ?  where id = ? ";
				// 产品认购状态 判断？ * 10 申请* 20 成功 21 资金退回 22 第三方处理失败* 30 失败
				if (subscribeResult) {
					result = dbHandle.update(updateSQl, thirdDealNo, 20, p2p_transaction_flow_id) == 1;
				} else {
					result = dbHandle.update(updateSQl, null, 30, p2p_transaction_flow_id) == 1;
				}
			}
			// 09:修改用户投资记录状态
			if (result && !subscribeResult) {
				// 0 全部未通过 1 部分通过 2 全部通过
				String sql = "update p2p_user_invest set status = ?,investVerifyAmount=0  where id = ? ";
				result = dbHandle.update(sql, 0, p2p_transaction_flow_id) == 1;
			}
			// 10:添加支付库 投资合同表
			if (result && subscribeResult) {
				StringBuffer sql = new StringBuffer();
				sql.append("insert into pay_p2p_relate(p2p_id,request_id,pay_id,product_id,extra) values(?,?,?,?,?)");
				List<Object> params = new ArrayList<Object>();
				params.add(p2p_transaction_flow_id);
				params.add(dealno);
				params.add(contractNo);
				params.add(p2p_project_id);
				params.add(null);
				result = dbPayHandle.update(sql.toString(), params.toArray()) == 1;
			}

			if (result && isWritingDB) {
				dbHandle.commit();
				dbPayHandle.commit();
				if (subscribeResult) {
					errorMsg.setLength(0);
					errorMsg.append("产品认购成功");
				}
				logger.debug(errorMsg.toString());
				return subscribeResult;
			} else {
				if (errorMsg.length() == 0) {
					errorMsg.append("产品认购失败,请稍候重试");
				}
				dbHandle.rollback();
				dbPayHandle.rollback();
			}
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			if (dbHandle != null)
				dbHandle.rollback();
			if (dbPayHandle != null)
				dbPayHandle.rollback();
			errorMsg.setLength(0);
			errorMsg.append("产品认购失败,请稍候重试");
		} finally {
			if (dbHandle != null)
				dbHandle = null;
			if (dbPayHandle != null)
				dbPayHandle = null;
		}
		logger.debug(errorMsg.toString());
		return false;
	}

}
